"""
Copyright 2009 Texas A&M University
 
Licensed under the Apache License, Version 2.0 (the "License"); you may not use 
this file except in compliance with the License. You may obtain a copy of the 
License at

http://www.apache.org/licenses/LICENSE-2.0
  
Unless required by applicable law or agreed to in writing, software distributed 
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
CONDITIONS OF ANY KIND, either express or implied. See the License for the 
specific language governing permissions and limitations under the License. 
"""

import unittest
from StringIO import StringIO
from xml.etree import ElementTree as etree

from meercat.base import Instance, Metadata

from meercat.harvester.metalib.harvester import MetalibHarvester

two_instances = '''<?xml version="1.0" encoding="UTF-8"?>
<file xmlns="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd
http://polychrest.tamu.edu:8331/aleph-cgi/load_schema.pl">
<knowledge_unit>
<record>
<controlfield tag="001">TEX00643</controlfield>
<datafield>marc record field</datafield>
</record>
<z58 base='Z58_BASE'>
<data>z58 data</data>
</z58>
<tab_sutrs>
<data>This is some random data</data>
</tab_sutrs>
<z39 filename="path/to/something">
<data>This is more random date</data>
</z39>
<category>
<data>Category data</data>
</category>
</knowledge_unit>
<knowledge_unit>
<record>
<controlfield tag="001">TEX00644</controlfield>
<datafield>marc record field</datafield>
</record>
<z58 base='Z58_BASE'>
<data>z58 data</data>
</z58>
<tab_sutrs>
<data>This is some random data</data>
</tab_sutrs>
<z39 filename="path/to/something">
<data>This is more random date</data>
</z39>
<category>
<data>Category data</data>
</category>
</knowledge_unit>
</file>'''

one_instance = '''<?xml version="1.0" encoding="UTF-8"?>
<file xmlns="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd
http://polychrest.tamu.edu:8331/aleph-cgi/load_schema.pl">
<knowledge_unit>
<record>
<controlfield tag="001">TEX00643</controlfield>
<datafield>marc record field</datafield>
</record>
<z58 base='Z58_BASE'>
<data>z58 data</data>
</z58>
<tab_sutrs>
<data>This is some random data</data>
</tab_sutrs>
<z39 filename="path/to/something">
<data>This is more random date</data>
</z39>
<category>
<data>Category data</data>
</category>
</knowledge_unit>
</file>'''

test_record = '''<?xml version="1.0" encoding="utf-8"?>
<record>
<controlfield tag="001">TEX00643</controlfield>
<datafield>marc record field</datafield>
</record>'''

test_z58 = '''<?xml version="1.0" encoding="utf-8"?>
<z58 base='Z58_BASE'><data>z58 data</data></z58>'''

test_tab_sutrs = '''<?xml version="1.0" encoding="utf-8"?>
<tab_sutrs><data>This is some random data</data></tab_sutrs>'''

test_z39 = '''<?xml version="1.0" encoding="utf-8"?>
<z39 filename="path/to/something"><data>This is more random date</data></z39>'''

test_category = '''<?xml version="1.0" encoding="utf-8"?>
<category><data>Category data</data></category>'''


class BaseTest(unittest.TestCase):
    _source_function = lambda h: StringIO('')
    _length = 0
    
    def setUp(self):
        self.harvester = MetalibHarvester(source = 'test',
                                          source_function = self._source_function)
        self.instances = self.harvester.harvest()
    
    def testLength(self):
        self.assertEqual(len(self.instances),self._length)

class TwoInstanceTest(BaseTest):
    _source_function = lambda h: StringIO(two_instances)
    _length = 2
    
    def testInstance1(self):
        i1 = Instance(source='metalib://test',
                      identifier='TEX00643')
        
        self.assertTrue(i1 in self.instances,
                        '%s not in %s' % (unicode(i1),unicode(self.instances)))
    
    def testInstance2(self):
        i2 = Instance(source='metalib://test',
                      identifier='TEX00644')
        self.assertTrue(i2 in self.instances,
                        '%s not in %s' % (unicode(i2),unicode(self.instances)))

class MetadataTest(BaseTest):
    _source_function = lambda h: StringIO(one_instance)
    _length = 1
    
    def setUp(self):
        super(MetadataTest,self).setUp()
    
    def testMarc(self):
        instance = self.instances[0]
        m = Metadata(source='metalib://test',format='marcxml',
                     value=etree.tostring(etree.fromstring(test_record),
                                          encoding='utf-8').replace('\n','').strip())
        self.assertTrue(m in instance.getMetadata(),
                        "Metadata not found: %s" % (m.getValue()))
    
    def testZ58(self):
        instance = self.instances[0]
        m = Metadata(source='metalib://test',format='metalib.z58',
                     value=etree.tostring(etree.fromstring(test_z58),
                                          encoding='utf-8').replace('\n','').strip())
        self.assertTrue(m in instance.getMetadata(),
                        "Metadata not found: %s" % (m.getValue()))
    
    def testTabSutrs(self):
        instance = self.instances[0]
        m = Metadata(source='metalib://test',format='metalib.tab_sutrs',
                     value=etree.tostring(etree.fromstring(test_tab_sutrs),
                                          encoding='utf-8').replace('\n','').strip())
        self.assertTrue(m in instance.getMetadata(),
                        "Metadata not found: %s" % (m.getValue()))
    
    def testZ39(self):
        instance = self.instances[0]
        m = Metadata(source='metalib://test',format='metalib.z39',
                     value=etree.tostring(etree.fromstring(test_z39),
                                          encoding='utf-8').replace('\n','').strip())
        self.assertTrue(m in instance.getMetadata(),
                        "Metadata not found: %s" % (m.getValue()))
    
    def testCategory(self):
        instance = self.instances[0]
        m = Metadata(source='metalib://test',format='metalib.category',
                     value=etree.tostring(etree.fromstring(test_category),
                                          encoding='utf-8').replace('\n','').strip())
        self.assertTrue(m in instance.getMetadata(),
                        "Metadata not found: %s" % (m.getValue()))

def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MetadataTest))
    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TwoInstanceTest))
    return suite

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(test_suite())